package stream

import (
	"encoding/json"
	"errors"
	"gluenet/pkg/apis"
	"gluenet/pkg/gerrors"
	"gluenet/pkg/meta"
	"strings"
)

func initStream(c *apis.StorageContext) {
	var arun []meta.AgentRunTime
	if err := c.DataBase.AgentRuntimeList(&arun); err != nil && !errors.Is(err, gerrors.DataNotFind) {
		c.Logger.Fatalf("list agent runtime errror")
	}

	for _, v := range arun {
		if v.Platform == apis.PlatfromGluenets {
			containers := strings.Split(v.Containers, "|")
			var cobj = map[string]string{}
			for _, vc := range containers {
				iv := strings.Split(vc, ",")
				if len(iv) == 2 {
					contain_name, app_guid := iv[0], iv[1]
					cobj[contain_name] = app_guid
				}
			}

			key := strings.Join([]string{apis.PlatfromGluenets, "agent_containers", v.AgentGuid}, "|")
			c.InfoFlusher.Info.Store(key, cobj)
			c.InfoFlusher.Func.Store(key, func(k, v interface{}) error {
				guid := strings.Split(k.(string), "|")[2]
				detail, i := make([]string, len(v.(map[string]string))), 0
				for contain_name, app_guid := range v.(map[string]string) {
					detail[i] = strings.Join([]string{contain_name, app_guid}, ",")
					i++
				}
				str := strings.Join(detail, "|")
				if err := c.DataBase.AgentRuntimeContainersUpdate(guid, str); err != nil {
					c.Logger.Errorf("update agent runtime container %v", err)
				}
				return nil
			})

		}
	}

	var irun []meta.InstanceRunTime
	if err := c.DataBase.InstanceRuntimeList(&irun); err != nil && !errors.Is(err, gerrors.DataNotFind) {
		c.Logger.Fatalf("list instance runtime errror")
	}

	for _, v := range irun {
		if v.AppPlatform == apis.PlatfromGluenets {
			// instance_containers
			// container_name,agent_guid | ...
			containers := strings.Split(v.Containers, "|")
			var cobj = make(map[string]string)
			for _, vc := range containers {
				iv := strings.Split(vc, ",")
				if len(iv) == 2 {
					contain_name, agent_guid := iv[0], iv[1]
					cobj[contain_name] = agent_guid
				}
			}

			key := strings.Join([]string{v.AppPlatform, "instance_containers", v.AppGuid}, "|")
			c.InfoFlusher.Info.Store(key, cobj)
			c.InfoFlusher.Func.Store(key, func(k, v interface{}) error {
				guid := strings.Split(k.(string), "|")[2]
				detail, i := make([]string, len(v.(map[string]string))), 0
				for contain_name, agent_guid := range v.(map[string]string) {
					detail[i] = strings.Join([]string{contain_name, agent_guid}, ",")
					i++
				}
				str := strings.Join(detail, "|")
				if err := c.DataBase.InstanceRuntimeContainerUpdate(guid, str); err != nil {
					c.Logger.Errorf("update agent runtime container %v", err)
				}
				return nil
			})

			// container_info
			// container_name,agent_guid | ...
			var containersInfo map[string]map[string]string
			if err := json.Unmarshal([]byte(v.ContainersInfo), &containersInfo); err != nil {
				c.Logger.Debugf("unmarshall error %v", err)
				containersInfo = make(map[string]map[string]string)
			}

			key2 := strings.Join([]string{v.AppPlatform, "container_info", v.AppGuid}, "|")
			c.InfoFlusher.Info.Store(key2, containersInfo)
			c.InfoFlusher.Func.Store(key2, func(k, v interface{}) error {
				guid := strings.Split(k.(string), "|")[2]
				bts, _ := json.Marshal(v)
				if err := c.DataBase.InstanceRuntimeContainerInfoUpdate(guid, string(bts)); err != nil {
					c.Logger.Errorf("update instance runtime container %v", err)
				}
				return nil
			})
		}
	}
}
